<?php

/**
 * Sean Huber CURL library, improved by mxFerreira
 *
 * This library is a basic implementation of CURL capabilities.
 *
 */
class CURL {
  private $debug;
  private $ch;
  private $callback;
  private $userAgent;
  private $referer;
  private $effectiveUrl;
  private $cookieFile;
  
  public function __construct($ua = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1'){
    $this->userAgent = $ua;
    $this->referer = array();
    $this->callback = false;
    $this->debug = 0;
    $this->cookieFile = tempnam(sys_get_temp_dir(), 'cookiejar');

    $this->ch = curl_init();
  }
  public function __destruct(){
    $this->close();
  }

  function debugLevel($level){
    $this->debug = $level;
  }

  function setHTTPVersion($version = 1.0){
    if($version == 1.0)
      curl_setopt($this->ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);

    if($version == 1.1)
      curl_setopt($this->ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
  }

  function getRefererUri(){
    $result = '';
    if(count($this->referer) > 0){
      $result .= (isset($this->referer['scheme']) ? $this->referer['scheme'] : 'http') . '://';
      $result .= isset($this->referer['user']) ? $this->referer['user'] . ':' : '';
      $result .= isset($this->referer['pass']) ? $this->referer['pass'] . '@' : '';
      $result .= isset($this->referer['host']) ? $this->referer['host'] : die("invalid referer URL\n");
      $result .= isset($this->referer['path']) ? $this->referer['path'] : '';
      $result .= isset($this->referer['query']) ? '?' . $this->referer['query'] : '';
      $result .= isset($this->referer['fragment']) ? '#' . $this->referer['fragment'] : '';
    }
    return $result;
  }
   
  function doRequest($method, $url, $vars) {
    $referer = $this->getRefererUri();

    if(! empty($this->effectiveUrl)){
      $url = $this->absoluteFromRelativePath($url);
    }

    curl_setopt($this->ch, CURLOPT_URL, $url);
    curl_setopt($this->ch, CURLOPT_COOKIEJAR, $this->cookieFile);
    curl_setopt($this->ch, CURLOPT_COOKIEFILE, $this->cookieFile);
    curl_setopt($this->ch, CURLOPT_USERAGENT, $this->userAgent);
    curl_setopt($this->ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($this->ch, CURLOPT_REFERER, $referer);

    curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($this->ch, CURLOPT_CAPATH, dirname(__FILE__));
    curl_setopt($this->ch, CURLOPT_CAINFO, dirname(__FILE__) . "/ca-bundle.crt");

    if ($method == 'POST') {
      curl_setopt($this->ch, CURLOPT_HTTPHEADER, array("Content-Type: application/x-www-form-urlencoded"));
      curl_setopt($this->ch, CURLOPT_POST, true);
      curl_setopt($this->ch, CURLOPT_POSTFIELDS, $vars);
    }

    if ($method == 'UPLOAD') {
      curl_setopt($this->ch, CURLOPT_HTTPHEADER, array("Content-Type: multipart/form-data"));
      curl_setopt($this->ch, CURLOPT_POSTFIELDS, $vars);
    }


    if($this->debug){
      curl_setopt($this->ch, CURLOPT_VERBOSE, true);
      curl_setopt($this->ch, CURLOPT_HEADER, true);
      curl_setopt($this->ch, CURLOPT_NOPROGRESS, false);
    }


    $data = curl_exec($this->ch);
    $this->effectiveUrl = curl_getinfo($this->ch, CURLINFO_EFFECTIVE_URL);

    if($this->debug > 1){
      echo "debug values:\n";
      echo "\trequest method: {$method}\n";
      echo "\trequest url: {$url}\n";
      echo "\trequest referer: {$referer}\n";
      echo "\trequest vars: {$vars}\n";
      if($this->debug > 2)
	echo "\trequest response: {$data}\n\n";
    }
    /*
     $data = $this->checkMetaTags($data);
     if($this->debug){
       echo "after metaCheck debug values:\n";
       echo "\trequest response: {$data}\n\n";
     }
    */

    $this->referer = parse_url($url);

    if ($this->callback){
      $callback = $this->callback;
      $this->callback = false;
      return call_user_func($callback, $data);
    } else {
      return $data;
    }
  }//end doRequest()

  function getEffectiveUrl(){
    return $this->effectiveUrl;
  }


  function absoluteFromRelativePath($rel){
    //my($scheme, $authority, $path, $query, $fragment) = $uri =~ m|(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?|;

    //it already is an absolute path with host 
    if(preg_match('|^[^:/?#]+://|', $rel, $m)){
      return $rel;
    }

    if(preg_match('|(?:([^:/?#]+):)?(?://(?:([^@]+)@)?([^/?#]*))?([^?#]*)|', $this->getEffectiveUrl(), $matchs)){
      list($full, $scheme, $authority, $host, $path) = $matchs;
      $authority = empty($authority) ? '' : $authority . '@';
    

      //it already is an absolute path without host
      if(preg_match('|^/(.*)$|', $rel, $matchs)){
	return sprintf('%s://%s/%s', $scheme, $authority . $host, $matchs[1]);
      }


      //everything by here really is an relative path

      $backNDirs = substr_count($rel, '../');
      $relFile = basename($rel);

      $basePath = dirname($path);
      while($backNDirs > 0){
	$basePath = dirname($basePath);
	$backNDirs--;
      }
      $basePath = preg_replace('|^/|', '', $basePath);
      $relPath = empty($basePath) ? $relFile : "$basePath/$relFile";

      return sprintf('%s://%s/%s', $scheme, $authority . $host, $relPath);
    }
    return $rel;
  }

  function download($urls, $callback) {
    $referer = $this->getRefererUri();
    $cmh = curl_multi_init();
    for($i = 0; $i < count($urls); $i++){
      $ch = curl_init();
      curl_setopt($ch, CURLOPT_READFUNCTION, $callback);
      curl_setopt($ch, CURLOPT_COOKIEJAR, $this->cookieFile);
      curl_setopt($ch, CURLOPT_COOKIEFILE, $this->cookieFile);
      curl_setopt($ch, CURLOPT_USERAGENT, $this->userAgent);
      curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
      curl_setopt($ch, CURLOPT_REFERER, $referer);
      curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
      curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
      curl_setopt($ch, CURLOPT_CAINFO, dirname(__FILE__) . "/ca-bundle.crt");

      curl_setopt($ch, CURLOPT_URL, $url[$i]);
      curl_multi_add_handle($cmh, $ch);
    }

    //em C curl_multi_perform
    curl_multi_exec($cmh);
    curl_multi_close($cmh);
  }//end download()

  function checkMetaTags($html){
    //<meta http-equiv="refresh" content="0; URL=/diario/diario.php ">
    if(preg_match('/<meta http-equiv="refresh" content=".*?;\s*URL=(.+?)">/i', $html, $matchs)){
      return $this->redirect(trim($matchs[1]));
    }else
      return $html;
  }//end checkMetaTags()

  function redirect($link){
    $uri = str_replace('//', '/', $this->referer['scheme'] . '://' . $this->referer['host'] . '/' . $link);
    return $this->get($uri);
  }//end redirect()

  function get($url) {
    return $this->doRequest('GET', $url, 'NULL');
  }//end get()

  function post($url, $vars) {
    if(is_array($vars)){
      $queryString = '';
      $sep = '';
      foreach($vars as $name => $value){
	$queryString .= $sep . $name . '=' . urlencode($value);
	$sep = '&';
      }
    }else
      $queryString = $vars;

    return $this->doRequest('POST', $url, $queryString);
  }//end post()
   
  function upload($url, $vars) {
    return $this->doRequest('UPLOAD', $url, $vars);
  }// end upload()

  function setCallback($func_name) {
    $this->callback = $func_name;
  }//end setCallback()

  function close(){
    if(file_exists($this->cookieFile)){
      unlink($this->cookieFile);
    }
    if(is_resource($this->ch)){
      curl_close($this->ch);
    }
  }//end close()


  function ftp_upload($src, $dest) {
    $fn = basename($src);
    //$dest = "ftp://user:passwd@server.com/incoming/$fn";
    $ch = curl_init();
   
    $fp = fopen($src,"r");
    curl_setopt($ch, CURLOPT_UPLOAD, 1);
    curl_setopt($ch, CURLOPT_TIMEOUT, 300);
    curl_setopt($ch, CURLE_OPERATION_TIMEOUTED, 300);
    curl_setopt($ch, CURLOPT_URL, $dest);
    curl_setopt($ch, CURLOPT_INFILE, $fp);
    curl_setopt($ch, CURLOPT_INFILESIZE, filesize($src));
    curl_exec($ch);
    fclose ($fp);
    $errorMsg = '';
    $errorMsg = curl_error($ch);
    $errorNumber = curl_errno($ch);
    curl_close($ch);
    return $errorNumber;
  }

  public static function getMatched($ER, $where, $matchID = NULL){
    if(is_array($matchID)){
      $result = array();
      if(preg_match($ER, $where, $matchs)){
	foreach($matchID as $id)
	  $result[] = $matchs[$id];
	return $result;
      }else
	return NULL;
    }elseif(isset($matchID)){
      return preg_match($ER, $where, $matchs) ? $matchs[$matchID] : NULL;
    }else{
      if(preg_match($ER, $where, $matchs)){
	return $matchs;
      }else{
	return NULL;
      }
    }
  }//end getMatched()

  public static function readFormFields($htm, & $formAction) {
    if(preg_match('/<form[^>]*action\s*=\s*([\'\"])(.*?)\1[^>]*>(.*?)<\/form>/si', $htm, $matchForm)){
      $formAction = $matchForm[2];
      $formContent= $matchForm[3];

      $result = array();

      if(preg_match_all('|<input\s+([^>]+?)/?\s*>|si', $formContent, $matchFields, PREG_SET_ORDER)){
	foreach($matchFields as $matchField){
	  if(preg_match_all('|(\w+)\s*=\s*["\']?(\w+)["\']?|', $matchField[1], $matchAttrs, PREG_SET_ORDER)){
	    $type = '';
	    $name = '';
	    $value = '';
	    foreach($matchAttrs as $matchAttr){
	      switch(strtolower($matchAttr[1])){
	      case 'type' :
		$type = $matchAttr[2];
		break;
	      case 'name' :
		$name = $matchAttr[2];
		break;
	      case 'value' :
		$value = $matchAttr[2];
		break;
	      }
	    }//end for attrs
	    if(! empty($name)){
	      if(strtolower($type) == 'radio'){
		if(preg_match('/checked(\s*=\s*\"(1|true)")?/i', $matchField[0], $m)){
		  $result[$name] = $value;
		}
	      }else{
		$result[$name] = $value;
	      }
	    }
	  }
	}
	return $result;
      }
    }
    
    return false;
  }
}//end class CURL


if ( !function_exists('sys_get_temp_dir')) {
  function sys_get_temp_dir() {
    if (!empty($_ENV['TMP'])) { return realpath($_ENV['TMP']); }
    if (!empty($_ENV['TMPDIR'])) { return realpath( $_ENV['TMPDIR']); }
    if (!empty($_ENV['TEMP'])) { return realpath( $_ENV['TEMP']); }
    $tempfile=tempnam(uniqid(rand(),TRUE),'');
    if (file_exists($tempfile)) {
      if(is_writeable($tempfile)){
	unlink($tempfile);
	return realpath(dirname($tempfile));
      }
    }
    return false;
  }
}



/*
	  foreach($matchs as $match){
	    $type = $match[1];
	    $name = $match[2];
	    $value = $match[3];
	    
	    if(strtolower($type) == 'radio'){
	      if(preg_match('/checked(\s*=\s*\"(1|true)")?/i', $match[0], $m)){
		$result[$name] = $value;
	      }
	    }else{
	      $result[$name] = $value;
	    }
	  }

	  array_push($forms, $result);
*/




/**
 * conseguir url absolutas a partir de url atual e url relativa
 *
 *

$uri = 'https://user:senha@host.domain.br/path/to/a/new/dir/file.ext?x=asdf&y=234#xkcd';

function doThis($rel){
  global $uri;

  //it already is an absolute path with host 
  if(preg_match('|^[^:/?#]+://|', $rel, $m)){
    return $rel;
  }

  if(preg_match('|(?:([^:/?#]+):)?(?://(?:([^@]+)@)?([^/?#]*))?([^?#]*)|', $uri, $matchs)){
    list($full, $scheme, $authority, $host, $path) = $matchs;
    $authority = empty($authority) ? '' : $authority . '@';
    

    //it already is an absolute path without host
    if(preg_match('|^/(.*)$|', $rel, $matchs)){
      return sprintf('%s://%s/%s', $scheme, $authority . $host, $matchs[1]);
    }


    //everything by here really is an relative path

    $backNDirs = substr_count($rel, '../');
    $relFile = basename($rel);

    $basePath = dirname($path);
    while($backNDirs > 0){
      $basePath = dirname($basePath);
      $backNDirs--;
    }
    $basePath = preg_replace('|^/|', '', $basePath);
    $relPath = empty($basePath) ? $relFile : "$basePath/$relFile";

    return sprintf('%s://%s/%s', $scheme, $authority . $host, $relPath);
  }
  return $rel;
}

echo "the absolute:\n\t$uri\n";

$rel = '../index.php'; 
printf("%-50s => %s\n", $rel, doThis($rel));

$rel = '../../index.php?asd=234&bcx=qwer'; 
printf("%-50s => %s\n", $rel, doThis($rel));

$rel = '../../../index.php'; 
printf("%-50s => %s\n", $rel, doThis($rel));


$rel = '/'; 
printf("%-50s => %s\n", $rel, doThis($rel));

$rel = '/path/to/index.php'; 
printf("%-50s => %s\n", $rel, doThis($rel));

$rel = 'http://www.unimontes.br'; 
printf("%-50s => %s\n", $rel, doThis($rel));

$rel = 'http://www.unimontes.br/'; 
printf("%-50s => %s\n", $rel, doThis($rel));

$rel = 'http://www.unimontes.br/index.php'; 
printf("%-50s => %s\n", $rel, doThis($rel));


exit(1);

*/














?>
